home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 201-225 / disk_214 / mandelvroom / src / contour.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  29KB  |  1,387 lines

  1. /*
  2.  * MandelVroom 2.0
  3.  *
  4.  * (c) Copyright 1987,1989  Kevin L. Clague, San Jose, CA
  5.  *
  6.  * All rights reserved.
  7.  *
  8.  * Permission is hereby granted to distribute this program's source
  9.  * executable, and documentation for non-comercial purposes, so long as the
  10.  * copyright notices are not removed from the sources, executable or
  11.  * documentation.  This program may not be distributed for a profit without
  12.  * the express written consent of the author Kevin L. Clague.
  13.  *
  14.  * This program is not in the public domain.
  15.  *
  16.  * Fred Fish is expressly granted permission to distribute this program's
  17.  * source and executable as part of the "Fred Fish freely redistributable
  18.  * Amiga software library."
  19.  *
  20.  * Permission is expressly granted for this program and it's source to be
  21.  * distributed as part of the Amicus Amiga software disks, and the
  22.  * First Amiga User Group's Hot Mix disks.
  23.  *
  24.  * contents: this file contains the code to open and close the contour
  25.  * palette tool.  It also contains the code that implements the contour
  26.  * commands.
  27.  */
  28.  
  29. #include "mandp.h"
  30.  
  31. UBYTE ContOpen;
  32.  
  33. struct Window *ContWind;
  34.  
  35. BYTE ContTitle[80];
  36.  
  37. struct NewWindow NewCont = {
  38.    0,200-80,                 /* start position           */
  39.    320,200,                  /* width, height            */
  40.    (UBYTE) 0, (UBYTE) -1,   /* detail pen, block pen    */
  41.    NULL,                     /* IDCMP flags */
  42.                              /* MandWind flags */
  43.    WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | NOCAREREFRESH | SMART_REFRESH |
  44.    REPORTMOUSE,
  45.    (struct Gadget *) NULL,   /* first gadget             */
  46.    (struct Image *) NULL,    /* user checkmark           */
  47.    (UBYTE *) NULL,           /* window title             */
  48.    (struct Screen *) NULL,   /* pointer to screen        */
  49.    (struct BitMap *) NULL,   /* pointer to superbitmap   */
  50.    80,80,320,200,            /* sizing                   */
  51.    CUSTOMSCREEN              /* type of screen           */
  52.    };
  53.  
  54.  
  55. SHORT Ceiling = 1023;
  56.  
  57. SHORT  NumContours = NUMCONTS;
  58. SHORT  FirstContour = 0;
  59. SHORT  SaveFirstCont = 0;
  60.  
  61. int    CurContour;
  62.  
  63. struct Gadget *ContGadget[DISPCONTS];
  64. struct Gadget *SelGadget[DISPCONTS];
  65.  
  66. UBYTE  Pattern[NUMCONTS+4];
  67. SHORT  PattSize;
  68.  
  69. static struct Gadget *ModGadget;
  70.  
  71. int    BarHotSpot;
  72.  
  73. LONG BarTop;
  74. LONG BarBot;
  75. LONG BarLeft;
  76. LONG BarRight;
  77. LONG BarWidth;
  78. LONG BarBoxTop;
  79. LONG BarBoxBot;
  80.  
  81. int ScaledFirst;
  82.  
  83. struct ContHoriz {
  84.   int CmdLeft;
  85.   int BarLeft;
  86.   int BarWidth;
  87.   int PenLeft;
  88.   int PenWidth;
  89. };
  90.  
  91. struct ContVert {
  92.   int CmdTop;
  93.   int BarTop;
  94.   int BarHeight;
  95.   int PenTop;
  96.   int PenHeight;
  97. };
  98.  
  99. static struct ContHoriz  Horiz_I     = {  3,   8,  262,   8, 6*33 };
  100. static struct ContHoriz  Horiz_II    = {  3,   8,  524,   8,12*32 + 4};
  101. static struct ContVert   Verticle_I  = { 11,   31,  10,  47, 42   };
  102. static struct ContVert   Verticle_II = { 11,   31,  14,  52, 82  };
  103.  
  104. static struct ContHoriz *CurH = &Horiz_I;
  105. static struct ContVert  *CurV = &Verticle_I;
  106.  
  107.  
  108. /*
  109.  * Contour related commands
  110.  */
  111.  
  112. /* Paint Command */
  113.  
  114. PaintCmd(Msg)
  115.   struct IntuiMessage *Msg;
  116. {
  117.   ReColor( CurPict );
  118.   DisplayBeep(screen);
  119.  
  120.   if ( CurPict->DrawPict ) {
  121.     ZoomBox( CurPict );
  122.   }
  123. }
  124.  
  125. SelContCmd(Msg)
  126.   struct IntuiMessage *Msg;
  127. {
  128.   struct Gadget *gadget;
  129.  
  130.   gadget = (struct Gadget *) Msg->IAddress;
  131.  
  132.   SetCurCont(GADG_NUM(gadget->GadgetID));
  133. }
  134.  
  135. SetHeightCmd(Msg)
  136.   struct IntuiMessage *Msg;
  137. {
  138.   struct Window *Window;
  139.   static struct Gadget *gadget;
  140.   struct PropInfo *propinfo;
  141.   static int knobhit;
  142.  
  143.   Window = Msg->IDCMPWindow;
  144.  
  145.   switch( Msg->Class ) {
  146.  
  147.     case GADGETDOWN:
  148.          gadget = (struct Gadget *) Msg->IAddress;
  149.          propinfo = (struct PropInfo *) gadget->SpecialInfo;
  150.  
  151.          if (knobhit = propinfo->Flags & KNOBHIT) {
  152.            ModifyIDCMP(Window, Window->IDCMPFlags | MOUSEMOVE);
  153.            State  = SETHEIGHTSTATE;
  154.          } else {
  155.            SetContourHeight(gadget);
  156.          }
  157.          break;
  158.  
  159.     case MOUSEMOVE:
  160.          SetContourHeight(gadget);                         /* potentio */
  161.          break;
  162.  
  163.     case GADGETUP:
  164.          if (knobhit) {
  165.            ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
  166.            ModAll();
  167.          } else {
  168.            SetContourHeight(gadget);                         /* potentio */
  169.            ShowValid();
  170.          }
  171.          State = IDLESTATE;
  172.          break;
  173.   }
  174. }
  175.  
  176. SetContCmd(Msg)  /* user can set height or pen */
  177.   struct IntuiMessage *Msg;
  178. {
  179.   struct Window  *Window;
  180.   struct Gadget  *gadget;
  181.   struct Picture *Pict;
  182.  
  183.   Window = Msg->IDCMPWindow;
  184.   gadget = (struct Gadget *) Msg->IAddress;
  185.  
  186.   switch( Msg->Class ) {
  187.  
  188.     case GADGETDOWN:
  189.          switch( WIND_TYPE(gadget->GadgetID) ) {
  190.  
  191.            case CONTYPE:
  192.                 if (gadget->GadgetID == CONTSET) {
  193.  
  194.                   SetToPointer();
  195.                   State = SETCONTSTATE;
  196.                 }
  197.                 break;
  198.  
  199.            case PALTYPE:
  200.                 if (GADG_TYPE(gadget->GadgetID) == PALPENS) {
  201.  
  202.                   State = IDLESTATE;
  203.                   SetContourPen( GADG_NUM(gadget->GadgetID) );
  204.                 }
  205.                 break;
  206.          }
  207.          break;
  208.  
  209.     case MOUSEBUTTONS:             /* selecting height from the picture */
  210.  
  211.          if (Msg->Code == SELECTDOWN) {
  212.            Pict = (struct Picture *) Window->UserData;
  213.            if ( Pict ) {
  214.              State = IDLESTATE;
  215.              DoWindowPick(Pict,MouseX,MouseY);
  216.            }
  217.          }
  218.          break;
  219.   }
  220. }
  221.  
  222. SmoothContCmd(Msg)  /* Smooth heights between two pens */
  223.   struct IntuiMessage *Msg;
  224. {
  225.   struct Gadget  *gadget;
  226.   int    t;
  227.  
  228.   /* Need contour selection to complete */
  229.  
  230.   gadget = (struct Gadget *) Msg->IAddress;
  231.  
  232.   if (Msg->Class == GADGETDOWN) {
  233.  
  234.     if (gadget->GadgetID == CONTSMTH) { /* Smooth command gadget */
  235.  
  236.       SetToPointer();
  237.       State = SMOOTHCONTSTATE;
  238.     } else {
  239.  
  240.       t = GADG_TYPE(gadget->GadgetID);
  241.  
  242.       if (t == CONTSELS || t == CONTPOTS) {
  243.  
  244.         t = GADG_NUM(gadget->GadgetID);
  245.  
  246.         /* smooth to last does decrement by one */
  247.  
  248.         if (t == CONTLAST)
  249.           *(CurPict->Heights + t) = 0x7fff;
  250.  
  251.         SmoothContours(CurContour, t);
  252.         State = IDLESTATE;
  253.       }
  254.     }
  255.   }
  256. }
  257.  
  258. CutContCmd(Msg)  /* Cut Pens between two contours */
  259.   struct IntuiMessage *Msg;
  260. {
  261.   struct Gadget  *gadget;
  262.   int    t;
  263.  
  264.   /* Need contour selection to complete */
  265.  
  266.   gadget = (struct Gadget *) Msg->IAddress;
  267.  
  268.   if (Msg->Class == GADGETDOWN) {
  269.  
  270.     if (gadget->GadgetID == CONTCUT) { /* Cut command gadget */
  271.  
  272.       SetToPointer();
  273.       State = CUTCONTSTATE;
  274.     } else {
  275.  
  276.       t = GADG_TYPE(gadget->GadgetID);
  277.  
  278.       if (t == CONTSELS || t == CONTPOTS) {
  279.  
  280.         t = GADG_NUM(gadget->GadgetID);
  281.  
  282.         CopyPattern(   CurContour, t);
  283.         DeleteContours(CurContour, t);
  284.         State = IDLESTATE;
  285.       }
  286.     }
  287.   }
  288. }
  289.  
  290. CopyContCmd(Msg)  /* Copy Pens between two contours */
  291.   struct IntuiMessage *Msg;
  292. {
  293.   struct Gadget  *gadget;
  294.   int    t;
  295.  
  296.   /* Need contour selection to complete */
  297.  
  298.   gadget = (struct Gadget *) Msg->IAddress;
  299.  
  300.   if (Msg->Class == GADGETDOWN)  {
  301.     if (WIND_TYPE(gadget->GadgetID) == CONTYPE) {
  302.  
  303.       if (gadget->GadgetID == CONTCOPY) { /* Copy command gadget */
  304.  
  305.         SetToPointer();
  306.         State = COPYCONTSTATE;
  307.       } else {
  308.  
  309.         t = GADG_TYPE(gadget->GadgetID);
  310.  
  311.         if (t == CONTSELS || t == CONTPOTS) {
  312.  
  313.           CopyPattern( CurContour, GADG_NUM(gadget->GadgetID));
  314.           State = IDLESTATE;
  315.         }
  316.       }
  317.     } else
  318.     if (WIND_TYPE(gadget->GadgetID) == PALTYPE) {
  319.       SetPenPattern(CurPen, GADG_NUM(gadget->GadgetID));
  320.       State = IDLESTATE;
  321.     }
  322.   }
  323. }
  324.  
  325. PasteContCmd(Msg)  /* Paste pens into contours */
  326.   struct IntuiMessage *Msg;
  327. {
  328.   struct Gadget  *gadget;
  329.   int    t;
  330.  
  331.   /* Need contour selection to complete */
  332.  
  333.   gadget = (struct Gadget *) Msg->IAddress;
  334.  
  335.   if (Msg->Class == GADGETDOWN) {
  336.  
  337.     if (gadget->GadgetID == CONTPASTE) { /* Paste command gadget */
  338.  
  339.       SetToPointer();
  340.       State = PASTECONTSTATE;
  341.     } else {
  342.  
  343.       t = GADG_TYPE(gadget->GadgetID);
  344.  
  345.       if (t == CONTSELS || t == CONTPOTS) {
  346.  
  347.         PastePattern( CurContour, GADG_NUM(gadget->GadgetID));
  348.         State = IDLESTATE;
  349.       }
  350.     }
  351.   }
  352. }
  353.  
  354. CeilingCmd(Msg)  /* Respond to ceiling gadget */
  355.   struct IntuiMessage *Msg;
  356. {
  357.   struct Gadget  *gadget;
  358.   struct PropInfo *PropInfo;
  359.   ULONG  VertPot;
  360.  
  361.   extern SHORT    Ceiling;
  362.  
  363.   if ( Msg->Class == GADGETUP ) {
  364.  
  365.     /* Need gadget up to complete */
  366.  
  367.     gadget = (struct Gadget *) Msg->IAddress;
  368.     PropInfo = (struct PropInfo *) gadget->SpecialInfo;
  369.  
  370.     VertPot  = PropInfo->VertPot;
  371.     VertPot ^= 0xffff;
  372.     VertPot += 1;
  373.     Ceiling = VertPot * CurPict->MaxIteration >> 16;
  374.  
  375.     ModAll();
  376.     State = IDLESTATE;
  377.   }
  378. }
  379.  
  380. SlideBarCmd(Msg)
  381.   struct IntuiMessage *Msg;
  382. {
  383.   struct Window *Window;
  384.   static SavedState;
  385.  
  386.   Window = Msg->IDCMPWindow;                  /* had better be ContWind */
  387.  
  388.   switch( Msg->Class ) {
  389.  
  390.     case MOUSEBUTTONS:                        /* slide is starting */
  391.          switch( Msg->Code ) {
  392.  
  393.            case SELECTDOWN:                   /* ImmediateCmd() filters */
  394.                 if (InBarBox()) {
  395.                   StartBarDrag();
  396.                   ModifyIDCMP(Window, Window->IDCMPFlags | MOUSEMOVE);
  397.                   SavedState = State;
  398.                   State = SLIDEBARSTATE;
  399.                 }
  400.                 break;
  401.  
  402.            case SELECTUP:                     /* slide is stoping */
  403.                 if (State == SLIDEBARSTATE) {
  404.                   ModAll();
  405.                   ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
  406.                   State = SavedState;
  407.                 }
  408.                 break;
  409.          }
  410.          break;
  411.  
  412.     case MOUSEMOVE:
  413.          DragBarBox();                        /* slide the bar */
  414.          break;
  415.   }
  416. }
  417.  
  418. ContNum(num)
  419.   int num;
  420. {
  421.   if (num == 32)
  422.     return(255);
  423.   else
  424.     return(num+FirstContour);
  425. }
  426.  
  427. RefreshContours()
  428. {
  429.   if ( ContWind ) {
  430.  
  431.     Ceiling = CurPict->MaxIteration;
  432.     DrawColorBox( ScaledFirst );
  433.     DrawColorBar();
  434.     ReDispPens();
  435.     ModAll();
  436.   }
  437. }
  438.  
  439. InBarBox()
  440. {
  441.   return(MouseX >= BarLeft + ScaledFirst             &&
  442.          MouseX <= BarLeft + BarWidth  + ScaledFirst &&
  443.          MouseY >= BarBoxTop                         &&
  444.          MouseY <= BarBoxBot                             );
  445. }
  446.  
  447. StartBarDrag()
  448. {
  449.   BarHotSpot = MouseX - BarLeft - ScaledFirst;
  450. }
  451.  
  452. DrawColorBar()
  453. {
  454.   register LONG x,s,sx;
  455.   register LONG dx  = XScale + 1;
  456.  
  457.   register struct RastPort *Rp = ContWind->RPort;
  458.  
  459.   register UBYTE *ColorPtr = CurPict->Pens;
  460.  
  461.   sx = BarLeft;
  462.  
  463.   for (x = 0; x < NumContours; x++ ) {
  464.  
  465.     SetAPen( Rp, (long) *ColorPtr++ );
  466.  
  467.     for (s = 0; s < dx; s++) {
  468.  
  469.       Move(Rp, sx,   BarTop );
  470.       Draw(Rp, sx++, BarBot );
  471.     }
  472.   }
  473.   DrawColorBox( ScaledFirst );
  474. }
  475.  
  476. DrawColorBox( Contour )
  477.   int Contour;
  478. {
  479.   register LONG Left = BarLeft + Contour;
  480.  
  481.   DrawBox( ContWind, Left, BarBoxTop, Left + BarWidth, BarBoxBot);
  482. }
  483.  
  484. DragBarBox()
  485. {
  486.   register int CurX;
  487.   static int OldCurX;
  488.  
  489.   CurX = MouseX;
  490.  
  491.   if (CurX == OldCurX)
  492.     return;
  493.  
  494.   OldCurX = CurX;
  495.  
  496.   if ( CurX < BarLeft + BarHotSpot )
  497.     CurX = BarLeft + BarHotSpot;
  498.   else
  499.   if ( CurX > BarRight - BarWidth + BarHotSpot )
  500.     CurX = BarRight - BarWidth + BarHotSpot;
  501.  
  502.   DrawColorBox( ScaledFirst );
  503.   DrawContBox( CurContour, NORMALPEN );
  504.  
  505.   ScaledFirst = (CurX - BarLeft - BarHotSpot);
  506.   FirstContour = ScaledFirst >> XScale;
  507.  
  508.   DrawColorBox( ScaledFirst );
  509.   DrawContBox( CurContour, HIGHLIGHTPEN );
  510.  
  511.   ReDispPens();
  512. }
  513.  
  514. SetContourPen( Pen )
  515.   USHORT Pen;
  516. {
  517.   register struct Image *Image;
  518.  
  519.   Image = (struct Image *) SelGadget[ CurContour ]->GadgetRender;
  520.  
  521.   Image = Image->NextImage;
  522.   Image->PlaneOnOff = Pen;
  523.  
  524.   RefreshGList( SelGadget[ CurContour ], ContWind, NULL, 1);
  525.  
  526.   *(CurPict->Pens + CurContour + FirstContour) = Pen;
  527.  
  528.   UpdateColorBar( Pen );
  529. }
  530.  
  531. UpdateColorBar( Pen )
  532.   USHORT Pen;
  533. {
  534.   register LONG ContourPos;
  535.   register UBYTE Overlap;
  536.   register LONG  x, sx;
  537.  
  538.   register struct RastPort *Rp = ContWind->RPort;
  539.  
  540.   ContourPos = ((CurContour + FirstContour) << XScale);
  541.  
  542.   Overlap =
  543.       ContourPos == ScaledFirst || ContourPos == ScaledFirst + BarWidth;
  544.  
  545.   if ( Overlap )
  546.     DrawColorBox( ScaledFirst );
  547.  
  548.   sx = BarLeft + ((CurContour + FirstContour) << XScale);
  549.  
  550.   SetAPen( Rp, (long) Pen );
  551.  
  552.   for (x = 0; x < XScale + 1; x++) {
  553.  
  554.     Move(Rp, sx,   BarTop );
  555.     Draw(Rp, sx++, BarBot );
  556.   }
  557.  
  558.   if ( Overlap )
  559.     DrawColorBox( ScaledFirst );
  560. }
  561.  
  562. SetCurCont(ContNum)
  563.   int ContNum;  /* relative to FirstCont */
  564. {
  565.   if (ContNum == CONTLAST)
  566.     return;
  567.  
  568.   SaveFirstCont = FirstContour;
  569.  
  570.   DrawContBox(CurContour, NORMALPEN );
  571.   DrawContBox(ContNum, HIGHLIGHTPEN );
  572.  
  573.   CurContour = ContNum;
  574.   SetContTitle(ContNum);
  575. }
  576.  
  577. SetContourHeight(gadget)
  578.   struct Gadget *gadget;
  579. {
  580.   struct  PropInfo *PropInfo;
  581.   ULONG   VertPot;
  582.   SHORT  *Contour;
  583.   int     ContNum;
  584.  
  585.   PropInfo = (struct PropInfo *) gadget->SpecialInfo;
  586.  
  587.   VertPot  = PropInfo->VertPot;
  588.  
  589.   VertPot ^= 0xffff;
  590.   VertPot += 1;
  591.  
  592.   ContNum = GADG_NUM(gadget->GadgetID);
  593.   Contour = CurPict->Heights + FirstContour + ContNum;
  594.  
  595.   if (*Contour <= Ceiling)
  596.     *Contour = VertPot * Ceiling >> 16;
  597.  
  598.   SetCurCont(ContNum);
  599. }
  600.  
  601. /*
  602.  * Set the contour window's new title
  603.  */
  604. SetContTitle(ContNum)
  605.   int ContNum;
  606. {
  607.   register SHORT Low, High;
  608.   register SHORT *Contour;
  609.   register UBYTE *Color;
  610.  
  611.   register char *fmt1 = "C: %-3d  P: %-2d  H: %3d-%d";
  612.   register char *fmt2 = "C: %-3d  P: %-2d  H: %3d";
  613.  
  614.   ContNum += FirstContour;
  615.  
  616.   Contour = CurPict->Heights + ContNum;
  617.  
  618.   Color = CurPict->Pens + ContNum;
  619.  
  620.   High = *Contour;
  621.  
  622.   if (ContNum != 0) {
  623.     Low  = *(Contour - 1);
  624.  
  625.     if (Low == High || Low - High == 1) {
  626.       sprintf(ContTitle, fmt2, ContNum, *Color, High);
  627.     } else {
  628.       if (Low < High)
  629.         sprintf(ContTitle, fmt2, ContNum, *Color, High);
  630.       else
  631.         sprintf(ContTitle, fmt1, ContNum, *Color, Low - 1, High);
  632.     }
  633.   } else {
  634.  
  635.     sprintf(ContTitle, fmt2, ContNum, *Color, High);
  636.   }
  637.   SetWindowTitles(ContWind, ContTitle, NULL);
  638. }
  639.  
  640. /*
  641.  * Set Selection's pen
  642.  */
  643. DrawContBox(Contour, pen)
  644.   int  Contour;
  645.   LONG pen;
  646. {
  647.   register LONG Left, Right, Top, Bottom;
  648.   register struct RastPort *Rp = ContWind->RPort;
  649.  
  650.   static LONG LastCont;
  651.  
  652.   int Cont;
  653.  
  654.   if ( pen == NORMALPEN ) {
  655.  
  656.     Cont = LastCont;
  657.   } else {
  658.  
  659.     LastCont = Cont = Contour + SaveFirstCont - FirstContour;
  660.   }
  661.  
  662.   if (Cont >= 0 && Cont < DISPCONTS) {
  663.  
  664.     Left = (6 << XScale) * Cont + CurH->PenLeft - 1;
  665.     Right = Left + (4 << XScale) + 2 + XScale;
  666.  
  667.     Top = CurV->PenTop - 1;
  668.     Bottom = Top + (4 << YScale) + 2 + YScale;
  669.  
  670.     SetDrMd(Rp, (LONG) JAM1);
  671.     SetAPen(Rp, pen);
  672.     /*
  673.      * Draw the new box
  674.      */
  675.     Move(Rp, Left,  Top   );
  676.     Draw(Rp, Right, Top   );
  677.  
  678.     if (pen == HIGHLIGHTPEN) SetAPen( Rp, SHADOWPEN );
  679.  
  680.     Draw(Rp, Right, Bottom);
  681.     Draw(Rp, Left,  Bottom);
  682.  
  683.     SetAPen( Rp, (long) pen );
  684.  
  685.     Draw(Rp, Left,  Top+1 );
  686.   }
  687. } /* DrawContBox */
  688.  
  689. /*
  690.  *  There was a window pick. Do what we need to do to service it
  691.  */
  692. DoWindowPick(Pict,MouseX,MouseY)
  693.   register struct Picture *Pict;
  694.   register SHORT MouseX,MouseY;
  695. {
  696.   register struct Window *Window = CurPict->Window;
  697.   register USHORT Height;
  698.  
  699.   if (Pict->Flags & NO_RAM_GENERATE)
  700.     return;
  701.  
  702.   Height = HeightPicked( Pict, MouseX, MouseY );
  703.   *(CurPict->Heights + CurContour + FirstContour) = Height;
  704.   ModAll();
  705. }
  706.  
  707. int
  708. HeightPicked( Pict, MouseX, MouseY )
  709.   register struct Picture *Pict;
  710.   register SHORT MouseX,MouseY;
  711. {
  712.   return( *(Pict->Counts + (MouseY - Pict->TopMarg) * Pict->CountX +
  713.                             MouseX - Pict->LeftMarg));
  714. }
  715.  
  716. /*
  717.  *  Smooth the heights over a subrange of contours
  718.  */
  719. SmoothContours(First,Second)
  720.   int First;
  721.   int Second;
  722. {
  723.   register USHORT Temp;
  724.   register SHORT *StartP,*EndP;
  725.   register float Diff,Start;
  726.  
  727.   First += SaveFirstCont;
  728.   Second = ContNum(Second);
  729.  
  730.   if (Second-First != 0) {
  731.  
  732.     if (Second < First) {
  733.       Temp = First;
  734.       First = Second;
  735.       Second = Temp;
  736.     }
  737.  
  738.     StartP = CurPict->Heights + First;
  739.     EndP   = CurPict->Heights + Second;
  740.  
  741.     Start =  (float) *StartP;
  742.     Diff  = ((float) *EndP - Start) / (float) (Second-First);
  743.  
  744.     if (Diff > -1.0) {
  745.       Diff = -1.0;
  746.     }
  747.  
  748.     for ( ; First < Second && Start > 0; First++)
  749.       *(StartP++ + 1) = (SHORT) (Start += Diff);
  750.  
  751.     if (Start == 0) {
  752.       for ( ; First < NumContours; First++) {
  753.         *StartP++ = 0;
  754.       }
  755.     }
  756.  
  757.     ModAll();
  758.   }
  759. } /* SmoothContours */
  760.  
  761. /*
  762.  *  Copy the pattern from the palette into pattern area
  763.  */
  764. CopyPattern(First,Second)
  765.   int First, Second;
  766. {
  767.   register int i, spacing;
  768.   register UBYTE *ColorPatt = CurPict->Pens;
  769.   register struct StringInfo *String =
  770.                   (struct StringInfo *) ModGadget->SpecialInfo;
  771.  
  772.   LONG Spacing;
  773.  
  774.   UBYTE *Last = ColorPatt + NUMCONTS;
  775.  
  776.   sscanf( String->Buffer, "%d", &Spacing );
  777.   spacing = Spacing;
  778.  
  779.   if ( spacing <= 0 ) {
  780.     return;
  781.   }
  782.  
  783.   First += SaveFirstCont;
  784.   Second = ContNum(Second);
  785.  
  786.   ColorPatt += First;
  787.  
  788.   if (First < Second) {
  789.  
  790.     PattSize = Second - First + 1;
  791.   } else {
  792.  
  793.     PattSize = First - Second + 1;
  794.     spacing = -spacing;
  795.   }
  796.  
  797.   for ( i = 0; i < PattSize && ColorPatt >= CurPict->Pens && ColorPatt < Last;
  798.         i++ ) {
  799.  
  800.     Pattern[ i ] = *ColorPatt;
  801.     ColorPatt += spacing;
  802.   }
  803.   PattSize = i;
  804. } /* CopyPattern */
  805.  
  806. /*
  807.  *  Set the pattern register to a list of consecutive pens
  808.  */
  809. SetPenPattern(First,Second)
  810.   register int First, Second;
  811. {
  812.   register LONG i, spacing;
  813.  
  814.   PattSize = Second - First;
  815.  
  816.   if ( PattSize < 0 ) {
  817.     PattSize = - PattSize;
  818.     spacing = -1;
  819.   } else {
  820.     spacing =  1;
  821.   }
  822.   PattSize += 1;
  823.  
  824.   for ( i = 0; i < PattSize; i++) {
  825.     Pattern[ i ] = First;
  826.     First += spacing;
  827.   }
  828. } /* SetPenPattern */
  829.  
  830. /*
  831.  *  Paste the pattern from the palette
  832.  */
  833. PastePattern(First,Second)
  834.   register int First, Second;
  835. {
  836.   register int i, Spacing;
  837.   register UBYTE *ColorPatt = CurPict->Pens;
  838.   register struct StringInfo *String =
  839.               (struct StringInfo *) ModGadget->SpecialInfo;
  840.  
  841.   LONG spacing;
  842.  
  843.   register UBYTE *Last = ColorPatt + NUMCONTS;
  844.  
  845.   if ( PattSize == 0 )
  846.     return;
  847.  
  848.   sscanf( String->Buffer, "%d", &spacing );
  849.  
  850.   Spacing = spacing;
  851.  
  852.   if ( Spacing < 1 )
  853.     return;
  854.  
  855.   First  += SaveFirstCont;
  856.   ColorPatt += First;
  857.   Second = ContNum(Second);
  858.  
  859.   if (First < Second ) {
  860.  
  861.     for ( i = 0; First <= Second && ColorPatt < Last;
  862.                  First += Spacing, i++ ) {
  863.  
  864.       if ( i == PattSize )
  865.         i = 0;
  866.  
  867.       *ColorPatt = Pattern[ i ];
  868.  
  869.       ColorPatt += Spacing;
  870.     }
  871.   } else {
  872.  
  873.     if (Second == 0) Second = 1;
  874.  
  875.     for ( i = 0; Second < First && ColorPatt >= CurPict->Pens;
  876.                  First -= Spacing, i++ ) {
  877.  
  878.       if ( i == PattSize )
  879.         i = 0;
  880.  
  881.       *ColorPatt = Pattern[ i ];
  882.  
  883.       ColorPatt -= Spacing;
  884.     }
  885.   }
  886.   DrawColorBox( ScaledFirst );
  887.   DrawColorBar();
  888.   ReDispPens();
  889. } /* PastePattern */
  890.  
  891. /*
  892.  *  Delete some contours from the contour list
  893.  */
  894. DeleteContours(First,Second)
  895.   register int First, Second;
  896. {
  897.   register USHORT Temp;
  898.   register UBYTE *StartCP, *EndCP;
  899.   register int    Size,i;
  900.  
  901.   struct StringInfo *String =
  902.          (struct StringInfo *) ModGadget->SpecialInfo;
  903.  
  904.   LONG spacing;
  905.  
  906.   sscanf( String->Buffer, "%d", &spacing );
  907.  
  908.   if ( spacing < 1 )
  909.     return;
  910.  
  911.   First  += SaveFirstCont;
  912.   Second = ContNum(Second);
  913.   Size = Second - First;
  914.  
  915.   if (Size) {
  916.  
  917.     if (Size < 0) {
  918.       Temp = First;
  919.       First = Second;
  920.       Second = Temp;
  921.  
  922.       Size = -Size;
  923.       Temp = Size % spacing;
  924.       First += Temp;
  925.     }
  926.  
  927.     StartCP = CurPict->Pens + First;
  928.  
  929.     if (spacing == 1) {
  930.       EndCP = CurPict->Pens + Second;
  931.  
  932.       Second = NUMCONTS - Second;
  933.  
  934.       for (i = 0; i < Second; i++) {
  935.         *StartCP++ = *EndCP++;
  936.       }
  937.     } else {
  938.       EndCP   = StartCP + 1;
  939.  
  940.       for ( ; First < Second; First += spacing ) {
  941.         for ( i = 0; i < spacing - 1; i++) {
  942.           *StartCP++ = *EndCP++;
  943.         }
  944.         EndCP++;
  945.       }
  946.     }
  947.  
  948.     while ( StartCP < CurPict->Pens + NUMCONTS ) {
  949.       *StartCP++ = NORMALPEN;
  950.     }
  951.  
  952.     DrawColorBox( ScaledFirst );
  953.     DrawColorBar();
  954.     ReDispPens();
  955.     ModAll();
  956.   }
  957. } /* DeleteContours */
  958.  
  959. /*
  960.  * ReDisplay all the contour potentiometer gadgets
  961.  */
  962. ModAll()
  963. {
  964.   register SHORT i;
  965.   register USHORT VertPot;
  966.   register USHORT Height;
  967.   register USHORT PrevHeight;
  968.  
  969.   register struct Gadget *PropGad = (struct Gadget *) ContGadget[0];
  970.   register struct Picture *Pict = CurPict;
  971.  
  972.   if (Ceiling > 0) {
  973.  
  974.     if (FirstContour == 0) {
  975.  
  976.       PrevHeight = Pict->Heights[ 0 ] + 1;
  977.  
  978.     } else {
  979.  
  980.       for (i = 0; i < FirstContour - 1; i++) {
  981.  
  982.         Height = Pict->Heights[ i ];
  983.  
  984.         if (Height < PrevHeight) {
  985.           PrevHeight = Height;
  986.         }
  987.       }
  988.     }
  989.  
  990.     for (i = 0; i < DISPCONTS; i++) {
  991.  
  992.       Height = CurPict->Heights[ i + FirstContour ];
  993.  
  994.       SetPotPen( PropGad, PrevHeight, Height );
  995.  
  996.       if (Height < PrevHeight)
  997.         PrevHeight = Height;
  998.  
  999.       if ( Height < Ceiling) {
  1000.  
  1001.         VertPot  = (Height<<16)/Ceiling;
  1002.         if (VertPot > 0)
  1003.           VertPot--;
  1004.         VertPot ^= 0xffff;
  1005.       } else
  1006.  
  1007.         VertPot = (USHORT) 0;
  1008.  
  1009.       NewModifyProp( PropGad, ContWind, NULL, FREEVERT|PROPBORDERLESS, 0L,
  1010.                (long) VertPot, 0L, 0xffff/Ceiling, 1L);
  1011.  
  1012.       PropGad = PropGad->NextGadget;
  1013.     }
  1014.   }
  1015. } /* ModAll */
  1016.  
  1017. /*
  1018.  * ReDisplay all the contour potentiometer gadgets
  1019.  */
  1020. ShowValid()
  1021. {
  1022.   register SHORT i;
  1023.   register USHORT Height;
  1024.   register USHORT PrevHeight;
  1025.  
  1026.   register struct Gadget *PropGad = (struct Gadget *) ContGadget[0];
  1027.   register struct Picture *Pict = CurPict;
  1028.  
  1029.   if (Ceiling > 0) {
  1030.  
  1031.     if (FirstContour == 0)
  1032.       PrevHeight = Pict->Heights[ 0 ] + 1;
  1033.     else
  1034.       PrevHeight = Pict->Heights[ FirstContour - 1 ];
  1035.  
  1036.     for (i = 0; i < DISPCONTS; i++) {
  1037.  
  1038.       Height = CurPict->Heights[ i + FirstContour ];
  1039.  
  1040.       if (SetPotPen( PropGad, PrevHeight, Height )) {
  1041.         RefreshGList( PropGad, ContWind, NULL, 1);
  1042.       }
  1043.  
  1044.       if (Height < PrevHeight)
  1045.         PrevHeight = Height;
  1046.  
  1047.       PropGad = PropGad->NextGadget;
  1048.     }
  1049.   }
  1050. } /* ShowValid */
  1051.  
  1052. SetPotPen( PropGad, PrevHeight, Height )
  1053.   register struct Gadget *PropGad;
  1054.   register USHORT PrevHeight;
  1055.   register USHORT Height;
  1056. {
  1057.   register int place,color;
  1058.   register struct Image *Image;
  1059.   extern int Num_vp_Colors;
  1060.  
  1061.   Image = (struct Image *) PropGad->GadgetRender;
  1062.  
  1063.   if (Height >= PrevHeight || Num_vp_Colors == 2)
  1064.     color = SHADOWPEN;
  1065.   else
  1066.     color = HIGHLIGHTPEN;
  1067.  
  1068.   if (Image->PlaneOnOff != color) {
  1069.     place = RemoveGadget( ContWind, PropGad );
  1070.     Image->PlaneOnOff = color;
  1071.     AddGadget( ContWind, PropGad, place );
  1072.     return(1);
  1073.   }
  1074.   return(0);
  1075. }
  1076.  
  1077. /*
  1078.  * ReDisplay all the pens gadgets
  1079.  */
  1080. ReDispPens()
  1081. {
  1082.   struct Gadget **Gadget = SelGadget;
  1083.  
  1084.   register LONG Left = (*Gadget)->LeftEdge;
  1085.   register LONG Top = (*Gadget)->TopEdge;
  1086.   register LONG Bot = Top + (4 << YScale) - 1;
  1087.  
  1088.   register LONG sixx  = 6 << XScale;
  1089.   register LONG fourx = (4 << XScale) - 1;
  1090.  
  1091.   register struct Image *Image;
  1092.  
  1093.   LONG i;
  1094.   struct RastPort *Rp = ContWind->RPort;
  1095.   UBYTE *Pen = CurPict->Pens + FirstContour;
  1096.  
  1097.   for (i = 0; i < DISPCONTS; i++) {
  1098.  
  1099.     Image = (struct Image *) (*Gadget)->GadgetRender;
  1100.  
  1101.     Image = Image->NextImage;
  1102.  
  1103.     SetAPen( Rp, (long) (Image->PlaneOnOff = *Pen++) );
  1104.  
  1105.     RectFill( Rp, Left, Top, Left + fourx, Bot);
  1106.  
  1107.     Left += sixx;
  1108.  
  1109.     Gadget++;
  1110.   }
  1111.  
  1112.   SetContTitle( 0 );
  1113. }
  1114.  
  1115. static LONG WindowWidth;
  1116. static LONG WindowHeight;
  1117.  
  1118. static struct Border *BarBorder;
  1119. static struct Border *PenBorder;
  1120. static struct Border *ClnBorder;
  1121.  
  1122. /*
  1123.  * Allocate all the gadgets and things for the contour window
  1124.  */
  1125. struct Gadget *MakeContours()
  1126. {
  1127.   struct Gadget   *FirstGadget;
  1128.   struct PropInfo *PropInfo;
  1129.  
  1130.   register struct Gadget *NextGadget;
  1131.   register struct IntuiText *Intui;
  1132.  
  1133.   register ULONG i,x,y;
  1134.   register ULONG c = 0;
  1135.  
  1136.   int fourx = 4 << XScale;
  1137.   int foury = 4 << YScale;
  1138.   LONG sixx = 6 << XScale;
  1139.   LONG sixy = 6 << YScale;
  1140.  
  1141.   int Left,Top,Width;
  1142.  
  1143.   char *str;
  1144.  
  1145.   if ( XScale )
  1146.     CurH = &Horiz_II;
  1147.   else
  1148.     CurH = &Horiz_I;
  1149.  
  1150.   if ( YScale )
  1151.     CurV = &Verticle_II;
  1152.   else
  1153.     CurV = &Verticle_I;
  1154.  
  1155.   FirstContour = 0;
  1156.   SaveFirstCont = 0;
  1157.  
  1158.   PenBorder = ClnBorder = BarBorder = NULL;
  1159.  
  1160.   BarBorder = ShadowBorder( BEVELEDUP, CurH->BarLeft - 4, CurV->BarTop - 2,
  1161.                                        CurH->BarWidth,    CurV->BarHeight);
  1162.   if (BarBorder == NULL) goto error;
  1163.  
  1164.   PenBorder = ShadowBorder( BEVELEDUP, CurH->PenLeft - 4, CurV->PenTop - 3,
  1165.                                        CurH->PenWidth,    CurV->PenHeight);
  1166.   if (PenBorder == NULL) goto error;
  1167.  
  1168.   Left = CurH->PenLeft + CurH->PenWidth + 2;
  1169.  
  1170.   ClnBorder = ShadowBorder( BEVELEDUP, Left,      CurV->PenTop-3,
  1171.                                        fourx + 5, CurV->PenHeight);
  1172.   if (ClnBorder == NULL) goto error;
  1173.  
  1174.   FirstGadget = NextGadget = MakePot( Left + 3, 30 << YScale,
  1175.                                      fourx, 32 << YScale, CONTCEIL, 0);
  1176.   if (NextGadget == NULL) goto error;
  1177.  
  1178.   NextGadget->Activation = GADGIMMEDIATE | FOLLOWMOUSE | RELVERIFY;
  1179.  
  1180.   Left = CurH->CmdLeft;
  1181.   Top = CurV->CmdTop;
  1182.  
  1183.   for (x = 0; x < 6; x++) {
  1184.  
  1185.     switch (x) {
  1186.       case 0: str = "Paint";  break;
  1187.       case 1: str = "Set";    break;
  1188.       case 2: str = "Smooth"; break;
  1189.       case 3: str = "Cut";    break;
  1190.       case 4: str = "Copy";   break;
  1191.       case 5: str = "Paste";  break;
  1192.     }
  1193.  
  1194.     Width = 8 * strlen( str ) + 6;
  1195.  
  1196.     NextGadget = NextGadget->NextGadget =
  1197.       MakeBool( Left, Top, Width, 13, NORMALPEN, CONTCNTL+x, NULL);
  1198.  
  1199.     if (NextGadget == NULL) goto error;
  1200.  
  1201.     Intui = NextGadget->GadgetText = ShadowIntui( str, 4, 3);
  1202.  
  1203.     if (Intui == NULL) goto error;
  1204.  
  1205.     Left += 4 + Width;
  1206.   }
  1207.  
  1208.   /* Set up color bar below command gadgets */
  1209.  
  1210.   BarBoxTop = CurV->BarTop;
  1211.   BarTop = BarBot = BarBoxTop + 1;
  1212.   BarBot += 4 << YScale;
  1213.   BarBoxBot = BarBot + 1;
  1214.  
  1215.   BarLeft = BarRight = CurH->BarLeft;
  1216.   BarRight += 256 << XScale;
  1217.   BarWidth = (DISPCONTS) << XScale;
  1218.  
  1219.   Width = 8 * strlen("Last") + 4;
  1220.  
  1221.   Top = CurV->PenTop;
  1222.  
  1223.   NextGadget = NextGadget->NextGadget =
  1224.     MakeBool( BarRight - Width + (2 << XScale), CurV->PenTop - 4, Width, 13,
  1225.               NORMALPEN, CONTLAST, NULL);
  1226.  
  1227.   if (NextGadget == NULL) goto error;
  1228.  
  1229.   Intui = NextGadget->GadgetText = ShadowIntui( "Last", 3, 3);
  1230.  
  1231.   if (Intui == NULL) goto error;
  1232.  
  1233.   NextGadget->GadgetText = Intui;
  1234.  
  1235.   i = CurH->PenLeft;
  1236.  
  1237.   /* Make Set of Gadgets */
  1238.  
  1239.   for (x = i, y = 0; y < DISPCONTS; x += sixx, y++) {
  1240.  
  1241.     SelGadget[y] = NextGadget = NextGadget->NextGadget =
  1242.       MakeBool(x, Top, fourx, foury, CurPict->Pens[ y + FirstContour ],
  1243.                CONTSEL+y, GADGIMAGE );
  1244.  
  1245.     if (NextGadget == NULL) goto error;
  1246.   }
  1247.  
  1248.   Top += sixy;
  1249.  
  1250.   FirstGadget->TopEdge = Top;
  1251.  
  1252.   Ceiling = CurPict->MaxIteration;
  1253.  
  1254.   /*
  1255.    * Allocate the potentiometer gadgets for contour window
  1256.    */
  1257.   for (x = i, y = 0; y < DISPCONTS; x += sixx, y++) {
  1258.  
  1259.     ContGadget[y] = NextGadget = NextGadget->NextGadget =
  1260.         MakePot(x, Top, 4 << XScale, 32 << YScale, CONTPOT+y, y);
  1261.  
  1262.     if (NextGadget == NULL) goto error;
  1263.  
  1264.     NextGadget->Activation = GADGIMMEDIATE | FOLLOWMOUSE | RELVERIFY;
  1265.  
  1266.     c = CurPict->Heights[ y ];
  1267.  
  1268.     if ( c < Ceiling )
  1269.       c = (ULONG) ((((Ceiling - ( c + 1 ))<<16)/(Ceiling)) & 0xffff);
  1270.     else
  1271.       c = (ULONG) 0;
  1272.  
  1273.     PropInfo = (struct PropInfo *) NextGadget->SpecialInfo;
  1274.  
  1275.     PropInfo->VertPot = c;
  1276.     PropInfo->VertBody = (USHORT) 0xffff/1024;
  1277.   }
  1278.  
  1279.   Top += 34 << YScale;
  1280.  
  1281.   ModGadget = NextGadget = NextGadget->NextGadget =
  1282.      MakeString( -28, -12 , 3, 0, "1" );
  1283.  
  1284.   if ( NextGadget == NULL ) goto error;
  1285.  
  1286.   NextGadget->Flags |= GRELBOTTOM | GRELRIGHT;
  1287.   NextGadget->GadgetText = Intui = ShadowIntui( "Mod", 0, -11 );
  1288.  
  1289.   if ( Intui == NULL ) goto error;
  1290.  
  1291.   WindowHeight = CurV->PenTop + CurV->PenHeight + (2 << YScale);
  1292.  
  1293.   if (XScale) {
  1294.     WindowWidth = 534;
  1295.   } else {
  1296.     WindowWidth = 271;
  1297.   }
  1298.   return( FirstGadget );
  1299.  
  1300. error:
  1301.   FreeBorder( BarBorder );
  1302.   FreeBorder( PenBorder );
  1303.   FreeBorder( ClnBorder );
  1304.   FreeGadgets( FirstGadget );
  1305.   return( NULL );
  1306.  
  1307. } /* MakeContours */
  1308.  
  1309. static struct Gadget *ContGadgets;
  1310.  
  1311. /*
  1312.  * Open the Contour window
  1313.  */
  1314. int
  1315. OpenContWind()
  1316. {
  1317.   register struct Gadget *gadgets;
  1318.   register struct RastPort *Rp;
  1319.  
  1320.   if (CurPict == NULL)
  1321.     return;
  1322.  
  1323.   if (ContWind == NULL) {
  1324.  
  1325.     gadgets = MakeContours();
  1326.  
  1327.     if (gadgets == NULL) {
  1328.       DispErrMsg("Can't allocate contour gadget chain",0);
  1329.       return(0);
  1330.     }
  1331.     ContWind = OpenMyWind(&NewCont, screen, NULL, WindowWidth,
  1332.                           WindowHeight);
  1333.  
  1334.     if (ContWind == NULL) {
  1335.       FreeGadgets(gadgets);
  1336.       return(0);
  1337.     }
  1338.     Rp = ContWind->RPort;
  1339.  
  1340.     SetAPen( Rp, NORMALPEN );
  1341.     RectFill( Rp, LEFTMARG, TOPMARG, WindowWidth, WindowHeight);
  1342.  
  1343.     ContGadgets = gadgets;
  1344.  
  1345.     BorderWindow( ContWind );
  1346.  
  1347.     DrawBorder( Rp, BarBorder, 0L, 0L );
  1348.     DrawBorder( Rp, PenBorder, 0L, 0L );
  1349.     DrawBorder( Rp, ClnBorder, 0L, 0L );
  1350.  
  1351.     FreeBorder( BarBorder );
  1352.     FreeBorder( PenBorder );
  1353.     FreeBorder( ClnBorder );
  1354.  
  1355.     AddGList( ContWind, gadgets, -1L, -1L);
  1356.  
  1357.     SetContTitle(0);
  1358.  
  1359.     DrawColorBar();
  1360.     DrawContBox( CurContour, HIGHLIGHTPEN );
  1361.  
  1362.     RefreshGadgets( ContWind->FirstGadget, ContWind, NULL );
  1363.     ModAll();
  1364.   } else {
  1365.  
  1366.     WindowToFront( ContWind );
  1367.   }
  1368.   ContOpen = 1;
  1369.   return( 1 );
  1370. } /* OpenContWind */
  1371.  
  1372. /*
  1373.  * Close the Mand window
  1374.  */
  1375. CloseContWind()
  1376. {
  1377.   if (ContWind != NULL) {
  1378.  
  1379.     NewCont.LeftEdge = ContWind->LeftEdge;
  1380.     NewCont.TopEdge = ContWind->TopEdge;
  1381.  
  1382.     CloseMyWind(ContWind,ContGadgets);
  1383.   }
  1384.   ContWind = NULL;
  1385. } /* ClosePalWind */
  1386.  
  1387.